import logging
import uuid
from datetime import datetime
from typing import List, Optional

from sqlalchemy import select

from app.admin.db import user_crud
from app.admin.schemas.user import UserCreate, UserUpdate
from app.db.session import AsyncSessionLocal
from app.models.role import Role, user_role
from app.models.user import User

# 配置日志
logger = logging.getLogger(__name__)


class UserService:
    """
    用户服务类，处理用户相关的业务逻辑
    """

    async def get_user(self, user_id: str, tenant_id: str) -> Optional[User]:
        """
        根据用户ID获取用户
        """
        async with AsyncSessionLocal() as db:
            return await user_crud.get_user(db, user_id, tenant_id)

    async def get_user_by_email(self, email: str) -> Optional[User]:
        """
        根据邮箱获取用户
        """
        async with AsyncSessionLocal() as db:
            return await user_crud.get_user_by_email(db, email)

    async def get_user_by_login_name(self, login_name: str) -> Optional[User]:
        """
        根据登录名获取用户
        """
        async with AsyncSessionLocal() as db:
            return await user_crud.get_user_by_login_name(db, login_name)

    async def get_users(self, skip: int = 0, limit: int = 100, tenant_id: str = None) -> List[User]:
        """
        获取用户列表，可按租户ID过滤
        """
        async with AsyncSessionLocal() as db:
            return await user_crud.get_users(db, skip=skip, limit=limit, tenant_id=tenant_id)

    async def create_user(self, user: UserCreate) -> User:
        """
        创建新用户
        """
        if user.id is None:
            user.id = str(uuid.uuid4().hex)
        user.create_at = datetime.now()
        user.update_at = datetime.now()
        async with AsyncSessionLocal() as db:
            return await user_crud.create_user(db=db, user=user)

    async def update_user(self, user_id: int, user_update: UserUpdate) -> Optional[User]:
        """
        更新用户信息
        """
        user_update.update_at = datetime.now()
        async with AsyncSessionLocal() as db:
            return await user_crud.update_user(db, user_id=user_id, user_update=user_update)

    async def delete_user(self, user_id: str, tenant_id: str) -> bool:
        """
        删除用户
        """
        async with AsyncSessionLocal() as db:
            return await user_crud.delete_user(db, user_id, tenant_id)

    async def check_email_exists(self, email: str) -> bool:
        """
        检查邮箱是否已存在
        """
        async with AsyncSessionLocal() as db:
            user = await user_crud.get_user_by_email(db, email)
            return user is not None

    async def check_login_name_exists(self, login_name: str) -> bool:
        """
        检查登录名是否已存在
        """
        async with AsyncSessionLocal() as db:
            user = await user_crud.get_user_by_login_name(db, login_name)
            return user is not None

    async def get_user_roles(self, user_id: str) -> List[Role]:
        """
        根据用户ID获取用户的角色列表
        """
        async with AsyncSessionLocal() as db:
            # 查询用户角色关联表
            stmt = select(Role).join(user_role).where(user_role.c.user_id == user_id)
            result = await db.execute(stmt)
            roles = result.scalars().all()
            return roles

    async def set_user_roles(self, user_id: str, role_ids: List[str]) -> bool:
        """
        为用户设置角色（会覆盖原有角色）
        """
        async with AsyncSessionLocal() as db:
            # 获取用户
            stmt = select(User).where(User.id == user_id)
            result = await db.execute(stmt)
            user = result.scalar_one_or_none()
            if not user:
                return False

            # 获取角色
            if role_ids:
                stmt = select(Role).where(Role.id.in_(role_ids))
                result = await db.execute(stmt)
                roles = result.scalars().all()
            else:
                roles = []

            # 设置角色（会覆盖原有角色）
            user.roles = roles

            await db.commit()
            await db.refresh(user)
            return True

    async def admin_reset_password(self, user_id: str) -> bool:
        """
        管理员重置用户密码为默认密码
        """
        logger.info(f"管理员重置用户密码: {user_id}")

        async with AsyncSessionLocal() as db:
            success = await user_crud.admin_reset_password(db, user_id)

            if success:
                logger.info(f"管理员重置密码成功: {user_id}")
                return True
            else:
                logger.warning(f"管理员重置密码失败: {user_id} - 用户不存在")
                return False

    async def change_password(self, user_id: str, old_password: str, new_password: str) -> bool:
        """
        用户修改密码（需要验证旧密码）
        """
        logger.info(f"用户尝试修改密码: {user_id}")

        async with AsyncSessionLocal() as db:
            success = await user_crud.change_password(db, user_id, old_password, new_password)

            if success:
                logger.info(f"密码修改成功: {user_id}")
                return True
            else:
                logger.warning(f"密码修改失败: {user_id} - 旧密码错误或用户不存在")
                return False


# 创建全局用户服务实例
user_service = UserService()
